//
//  VideoPlayView.m
//  Player
//
//  Created by yueshi－mac1 on 15/12/15.
//  Copyright © 2015年 lanou. All rights reserved.
//

#import "VideoPlayView.h"
#import "UISlider+UISlider_touch.h"
#import "UIImageView+VideoImage.h"
#define KScreenWidth [[UIScreen mainScreen]bounds].size.width
#define KScreenHeight [[UIScreen mainScreen]bounds].size.height
#define KDefaulTimeStr @"00:00"
#define KToolViewHeight 40
#define KTimeFontSize 12

@interface VideoPlayView (){
    PanDirection direction;
}

@property (nonatomic, strong) AVPlayer              *player;//播放器对象
@property (weak, nonatomic) AVPlayerLayer           *playerLayer;// 播放器的Layer

@property (strong, nonatomic) UIImageView           *imageView;//播放器容器

@property (nonatomic, strong) UIButton              *playButton;//播放/暂停按钮

@property (nonatomic, strong) UIView                *toolView;
@property (nonatomic, strong) UILabel               *currentTimeLabel;// 当前播放时间
@property (nonatomic, strong) UILabel               *durationTimeLabel; // 播放时间长度
@property (nonatomic, strong) UISlider              *progress;//播放进度条
@property (nonatomic, strong) UISlider              *playableProgress;//加载进度条

@property (nonatomic, assign) BOOL                  isSliding;//进度条是否被拖动(拖动的话则不受播放进度控制)
@property (nonatomic, strong) UIActivityIndicatorView *loading;//小菊花
@property (nonatomic, assign) BOOL                    istouched;//暂停状态是由使用者手动触发的还是网络加载不畅出发的

@end

@implementation VideoPlayView

- (AVPlayer *)player{
    if (!_player) {
        // 初始化Player
        _player = [[AVPlayer alloc] init];
    }
    return _player;
}

- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        [self setupUI];
    }
    return self;
}

-(void)setupUI{
    self.backgroundColor = [UIColor blackColor];
    //imageView
    self.imageView = [[UIImageView alloc] init];
    [self addSubview:self.imageView];
    
    //创建播放器层
    self.playerLayer=[AVPlayerLayer playerLayerWithPlayer:self.player];
    self.playerLayer.frame=self.imageView.frame;
    self.playerLayer.videoGravity=AVLayerVideoGravityResizeAspect;//视频填充模式
    [self.imageView.layer addSublayer:self.playerLayer];
    
    //  PlayButton
    self.playButton = [UIButton buttonWithType:UIButtonTypeCustom];
    UIImage *playImage = [UIImage imageNamed:@"play"];
    [self.playButton setImage:playImage forState:UIControlStateNormal];
    [self.playButton setImage:[UIImage imageNamed:@"stop"] forState:UIControlStateSelected];
    self.playButton.frame = CGRectMake(0, 0, playImage.size.width, playImage.size.height);
    [self addSubview:self.playButton];

    // toolView
    self.toolView = [[UIView alloc] init];
    self.toolView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.8];
    self.toolView.hidden = YES;
    [self addSubview:self.toolView];
    
    //  currentTimeLabel
    self.currentTimeLabel = [[UILabel alloc] init];
    self.currentTimeLabel.text = KDefaulTimeStr;
    self.currentTimeLabel.font = [UIFont systemFontOfSize:KTimeFontSize];
    self.currentTimeLabel.textColor = [UIColor whiteColor];
    [self.toolView addSubview:self.currentTimeLabel];
    
    //  durationTimeLabel
    self.durationTimeLabel = [[UILabel alloc] init];
    self.durationTimeLabel.text = KDefaulTimeStr;
    self.durationTimeLabel.font = [UIFont systemFontOfSize:KTimeFontSize];
    self.durationTimeLabel.textColor = [UIColor whiteColor];
    [self.toolView addSubview:self.durationTimeLabel];
    
    
    // playalbe slider
    self.playableProgress =[[UISlider alloc]init];
    //  滑块左侧颜色
    self.playableProgress.minimumTrackTintColor = [UIColor colorWithRed:220/255.0 green:220/255.0 blue:220/255.0 alpha:1];
    //  滑块右侧颜色
    self.playableProgress.maximumTrackTintColor = [UIColor colorWithRed:241/255.0 green:241/255.0 blue:241/255.0 alpha:0.5];
    
    UIImage *thumbImageEmp = [[UIImage alloc]init];
    [self.playableProgress setThumbImage:thumbImageEmp forState:UIControlStateNormal];
    [self.playableProgress setThumbImage:thumbImageEmp forState:UIControlStateSelected];
    self.playableProgress.userInteractionEnabled = NO;
    [self.toolView addSubview:self.playableProgress];
    
    // progress slider
    self.progress =[[UISlider alloc]init];
    //  滑块左侧颜色
    self.progress.minimumTrackTintColor = ThemeColor;
    //  滑块右侧颜色
    self.progress.maximumTrackTintColor = [UIColor clearColor];
    
    UIImage *thumbImage0 = [UIImage imageNamed:@"Oval 1"];
    [self.progress setThumbImage:thumbImage0 forState:UIControlStateNormal];
    [self.progress setThumbImage:thumbImage0 forState:UIControlStateSelected];
    [self.progress addTarget:self action:@selector(valueChange:other:) forControlEvents:UIControlEventValueChanged];
    [self.progress addTapGestureWithTarget:self action:@selector(resetSlider)];
    [self.toolView addSubview:self.progress];
    
    // 小菊花
    self.loading = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    self.loading.frame = CGRectMake(0, 0, 30, 30);
    [self addSubview:self.loading];
}

- (void)layoutSubviews{
    [super layoutSubviews];
    
    self.imageView.frame = self.bounds;

    self.playerLayer.frame=self.imageView.frame;

    self.playButton.center = self.imageView.center;
    
    self.toolView.frame = CGRectMake(0, self.height - KToolViewHeight, self.width, KToolViewHeight);
    
    CGSize timeSize = [@"66:66" sizeWithFont:[UIFont systemFontOfSize:KTimeFontSize]];
    self.currentTimeLabel.frame = CGRectMake(15, self.toolView.height/2 - timeSize.height/2, timeSize.width, timeSize.height);
    
    self.durationTimeLabel.frame = CGRectMake(self.toolView.width - timeSize.width - 15, self.currentTimeLabel.y, timeSize.width, timeSize.height);
    
    self.playableProgress.frame = CGRectMake(CGRectGetMaxX(self.currentTimeLabel.frame) + 10, self.toolView.height/2 - 15/2, self.toolView.width - 15*2 - 10*2 - timeSize.width *2, 15);
    
    self.progress.frame = self.playableProgress.frame;
    
    self.loading.center = self.imageView.center;
}

- (void)setVideoUrlStr:(NSString *)videoUrlStr{
    if (!_videoUrlStr) {
        //  添加触控事件
        [self addGesture];
    }
    _videoUrlStr = videoUrlStr;
    
    [self.imageView setImageWithVideoUrl:[NSURL URLWithString:videoUrlStr] placeholderImageStr:@"bg_loding_defalut"];
    
    [self reset];
}

//  初始化播放器
- (void)initPlayer {
    AVPlayerItem *playerItem=[self getPlayItem];
    [self.player replaceCurrentItemWithPlayerItem:playerItem];
    [self addProgressObserver];
    [self addObserverToPlayerItem:playerItem];
    
    //  添加通知
    [self addNotification];

    
}

//  获得播放媒介
-(AVPlayerItem *)getPlayItem{
    AVPlayerItem *playerItem=[AVPlayerItem playerItemWithURL:[NSURL URLWithString:self.videoUrlStr]];
    return playerItem;
}

/**
 *  给AVPlayerItem添加监控
 *
 *  @param playerItem AVPlayerItem对象
 */
-(void)addObserverToPlayerItem:(AVPlayerItem *)playerItem{
    //监控状态属性，注意AVPlayer也有一个status属性，通过监控它的status也可以获得播放状态
    [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    //监控网络加载情况属性
    [playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
}

-(void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem{
    [playerItem removeObserver:self forKeyPath:@"status"];
    [playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
}

//  添加触控事件
- (void)addGesture {
    //默认一开始是不播放的，相当于手动暂停
    self.istouched = YES;
    // 点击事件
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(viewOnClick)];
    [self addGestureRecognizer:tap];
    
    // 按钮点击事件
    [self.playButton addTarget:self action:@selector(playClick:) forControlEvents:UIControlEventTouchUpInside];
    
    //  滑动事件
//    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];
//    [self addGestureRecognizer:pan];
}

/**
 *  添加播放器通知
 */
-(void)addNotification{
    [self removeNotification];
    
    //给AVPlayerItem添加播放完成通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:KStopVideoPlayNortif object:self];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stopPlay:) name:KStopVideoPlayNortif object:nil];
}

-(void)removeNotification{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void) stopPlay:(NSNotification *)notify{
    UIView *view = [notify object];
    if (view != self) {
        [self reset];
    }
}


#pragma mark - 点击播放/暂停按钮
- (void) playClick:(UIButton *)sender{
    //  播放状态->暂停
    if (self.player.rate==1) {
        self.istouched = YES;
        [self.player pause];
        self.playButton.selected = NO;
        
        [self playButtonAppear];
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(playButtonDisappear) object:nil];
        
        if([self.loading isAnimating]) [self.loading stopAnimating];
        //  暂停状态->播放
    }else {
        if (self.progress.value >= 1) {
            self.progress.value = 0;
            [self resetSlider];
            return;
        }
        
        if (!self.player.currentItem) {
            [self initPlayer];
            self.imageView.image = nil;
            [self.loading startAnimating];
        }else{
            [self.player play];
        }
        
        self.istouched = NO;
        self.playButton.selected = YES;
        
        
        [UIView animateWithDuration:0.3 animations:^{
            self.playButton.alpha = 0;
        }];
        [self performSelector:@selector(playButtonDisappear) withObject:nil afterDelay:3];
    }
}

// 点击整个背景
- (void)viewOnClick {
    if (!self.player.currentItem) {
        [self playClick:self.playButton];
    }else{
        
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(playButtonDisappear) object:nil];
        if (self.toolView.hidden) {
            [self playButtonAppear];
            [self performSelector:@selector(playButtonDisappear) withObject:nil afterDelay:3];
        }else{
            [self playButtonDisappear];
        }
    }
}

//  控件出现(动画)
- (void)playButtonAppear {
    [UIView animateWithDuration:0.5 animations:^{
        if(!self.loading.isAnimating){
            self.playButton.hidden = NO;
        }
        self.toolView.hidden = NO;
        
        self.playButton.alpha = 1;
        self.toolView.alpha = 1;
    }completion:^(BOOL finished) {
        
    }];
}

//  控件消失(动画)
-(void)playButtonDisappear {
    if (!self.playButton.selected) {
        return;
    }
    
    [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
        self.playButton.alpha = 0;
        self.toolView.alpha = 0;
    } completion:^(BOOL finished) {
        self.playButton.hidden = YES;
        self.toolView.hidden = YES;
    }];
}

//  滑动事件
- (void)panAction:(UIPanGestureRecognizer *)pan {
    //  滑动速率
    CGPoint velocityPoint = [pan velocityInView:pan.view];
    switch (pan.state) {
        case UIGestureRecognizerStateBegan:{
            self.isSliding = YES;
            [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(playButtonDisappear) object:nil];
            //  判断滑动方向
            if (fabs(velocityPoint.x) > fabs(velocityPoint.y)) {
                direction = PanDirectionHorizontalMoved;
            }else {
                direction = PanDirectionVerticalMoved;
            }
            break;
        }
        case UIGestureRecognizerStateChanged:{
            switch (direction) {
                case PanDirectionHorizontalMoved:{
                    //  水平移动
                    self.progress.value += velocityPoint.x / 100000;
                }
                case PanDirectionVerticalMoved:{
                    //  垂直移动
                    self.player.volume -= velocityPoint.y / 10000;   //  播放器音量
                }
            }
            break;
        }
        case UIGestureRecognizerStateEnded:
            self.isSliding = NO;
            [self performSelector:@selector(playButtonDisappear) withObject:self afterDelay:3];
            switch (direction) {
                case PanDirectionHorizontalMoved:{
                    //  水平移动 结束
                    [self resetSlider];
                    break;
                }
                case PanDirectionVerticalMoved:{
                    //  垂直移动结束
                    break;
                }
                default:
                    break;
            }
            break;
        default:
            break;
    }
}


//  更新进度条位置并播放
- (void)resetSlider {
    if (CMTimeGetSeconds(self.player.currentItem.duration)) {
        CMTime dragedCMTime = CMTimeMake(self.progress.value * CMTimeGetSeconds([self.player.currentItem duration]), 1);
        [self.player pause];
        [self.player seekToTime:dragedCMTime completionHandler:^(BOOL finish){
            [self playClick:self.playButton];
        }];
    }
    
}

//  拖动进度条
- (void)valueChange:(UISlider *)progress other:(UIEvent *)event {
    UITouch *touch = [[event allTouches] anyObject];
    switch (touch.phase) {
            //  触摸开始
        case UITouchPhaseBegan:
            self.isSliding = YES;
            [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(playButtonDisappear) object:nil];
            break;
            //  触摸中
        case UITouchPhaseMoved:
            break;
            //  触摸结束
        case UITouchPhaseEnded:
            self.isSliding = NO;
            [self performSelector:@selector(playButtonDisappear) withObject:nil afterDelay:3];
            [self resetSlider];
            break;
        default:
            break;
    }
}

//  计算当前时间
- (NSString *)currentTimeToString:(NSTimeInterval)currentTime {
    NSInteger static minit;
    NSInteger static second;
    minit = currentTime / 60;
//    second = currentTime - 60 * minit;
    second = (NSInteger)currentTime % 60;
    NSString *time = [NSString stringWithFormat:@"%02ld:%02ld", minit, second];
    return time;
}

#pragma mark - 监控
/**
 *  给播放器添加进度更新
 */
-(void)addProgressObserver{
    AVPlayerItem *playerItem=self.player.currentItem;
    //这里设置每秒执行一次
    __weak typeof(self) weakSelf=self;  //设置self的弱应用放置block循环引用
    [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        float current=CMTimeGetSeconds(time);
        float total=CMTimeGetSeconds([playerItem duration]);
        if (current) {
            if (!weakSelf.isSliding) {
                weakSelf.progress.value = current/total;
            }
            weakSelf.currentTimeLabel.text = [weakSelf currentTimeToString:current];
        }
    }];
}

/**
 *  通过KVO监控播放器状态
 *
 *  @param keyPath 监控属性
 *  @param object  监视器
 *  @param change  状态改变
 *  @param context 上下文
 */
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    AVPlayerItem *playerItem=object;
    if ([keyPath isEqualToString:@"status"]) {
        AVPlayerStatus status= [[change objectForKey:@"new"] intValue];
        if(status==AVPlayerStatusReadyToPlay){
            float current = CMTimeGetSeconds([playerItem currentTime]);
            self.currentTimeLabel.text = [self currentTimeToString:current];
            
            float total = CMTimeGetSeconds([playerItem duration]);
            self.durationTimeLabel.text = [self currentTimeToString:total];
            
            if (self.playButton.selected) {
                [self.player play];
            }
        }
    }else if([keyPath isEqualToString:@"loadedTimeRanges"]){
        NSArray *array=playerItem.loadedTimeRanges;
        CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次缓冲时间范围
        float startSeconds = CMTimeGetSeconds(timeRange.start);
        float durationSeconds = CMTimeGetSeconds(timeRange.duration);
        NSTimeInterval totalBuffer = startSeconds + durationSeconds;//缓冲总长度
        self.playableProgress.value = totalBuffer / CMTimeGetSeconds([playerItem duration]);
        
        if (!_istouched) {
            if (self.player.rate==0) {
                if(totalBuffer - CMTimeGetSeconds([playerItem currentTime]) > 5){
                    [self.player play];
                }
                
                if (self.playableProgress.value < 1) {
                     [_loading startAnimating];
                    return;
                }
            }
             [_loading stopAnimating];
        }
    }
}

/**
 *  播放完成通知
 *
 *  @param notification 通知对象
 */
//  播放完成
-(void)playbackFinished:(NSNotification *)notification{
    [self reset];
}

- (void)reset{
    self.istouched = YES;
    
    if (self.player.currentItem) {
        [self.player pause];
        [self.player seekToTime:CMTimeMake(1, 1)];
        
        [self removeObserverFromPlayerItem:self.player.currentItem];
        [self removeNotification];
        
        [self.player replaceCurrentItemWithPlayerItem:nil];
        
        [self.imageView setImageWithVideoUrl:[NSURL URLWithString:self.videoUrlStr] placeholderImageStr:@"bg_loding_defalut"];
    }
    
    self.progress.value = 0;
    
    self.currentTimeLabel.text = [self currentTimeToString:0];
    self.playButton.selected = NO;
    
    [UIView animateWithDuration:0.5 animations:^{
        self.playButton.alpha = 1;
        self.playButton.hidden = NO;
    }];
    
    [UIView animateWithDuration:0.3 animations:^{
        self.toolView.alpha = 0;
    }completion:^(BOOL finished) {
        self.toolView.hidden = YES;
    }];
    
    if([self.loading isAnimating]) [self.loading stopAnimating];
    
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(playButtonDisappear) object:nil];
}

- (void)dealloc{
    //    [self.player.currentItem cancelPendingSeeks];
    //    [self.player.currentItem.asset cancelLoading];
    
    [self removeObserverFromPlayerItem:self.player.currentItem];
    [self removeNotification];
    
    [self.player replaceCurrentItemWithPlayerItem:nil];
    
}

@end
